<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    
//订阅发布器
// 每个数据都有一个自己的订阅发布器
//他被定义在defineReactive方法里 存在闭包里 
class Dep{
    constructor(){
        this.subs=[]
    }
    //找到需要更新的
    depend(){
        this.subs.push(Dep.target)
        console.log(this.subs)
    }
    //更新
    notify(){
        this.subs.forEach(watcher=>{
            watcher.unpdate()
        })
    }
}


        
 //观察者
 class Wactch{
     constructor(data,key){
         this.value = data,
         this.key = key
         Dep.target =this
         console.log(Dep.target)
         this.get()
         Dep.target=null
        console.log(Dep.target)
     }  
     
     
     get(){
         return this.value[this.key]
     }
     //观察者的响应动作 更新页面模板
     unpdate(){
        console.log("监听"+this.key+"的watcher被触发了,新的值="+this.get())
     }
 }

















    function defineReactive(obj,key){
        let value  = obj[key]
        console.log(value)  //{name:张三，desc:"法外光秃"}

        let dep = new Dep()

        observe(value) //递归处理value
        Object.defineProperty(obj,key,{
            get:function(){
                console.log("正在访问:" +key)
                //有一个观察者 在访问这个数据 所有应该将这个观察者存入订阅发布中心
                if(Dep.target){
                    dep.depend()
                }               
                return value
            },
            set:function(newValue){
                console.log("正在修改"+key)
                value=newValue
                observe(newValue) //递归处理新数据
                dep.notify()
            }




        })




    }


        class Observe{
            constructor(obj,){
                this.value = obj
            if(Array.isArray(obj)){
                this.observeArry()
            }else{
                this.walk()
            }
            }

            observeArry(){
                for(let i = 0;i<this.value.length;i++){
                    observe(this.value[i])
                }
            }
            //是对象
            walk(){
                Object.keys(this.value).forEach(key=>{
                    console.log(key) //count user list

                    defineReactive(this.value,key)
                })
            }
         
        }








        function observe(value){
            //如果value 不是一个对象 直接返回
            if(typeof value != "object") return
        
           let vn=  new Observe(value)
           console.log(vn)
        }





        function Vue(options){
            //将option中的内容 添加到当前对象实例中
            Object.keys(options).forEach(key=>{
                this[key] = options[key]
            })

            //处理data数据 将它变成响应式的 可监测的
            console.log(this)

            observe(this.data)
            console.log(this.data)

            new Wactch(this,"data")
            new Wactch(this.data,"conut")
            new Wactch(this.data,"user")
            new Wactch(this.data,"list")



        }

        let vm = new Vue({
            data:{
                count:123,
                user:{
                    name:'张三',
                    desc:"法外光秃"
                },
                list:["yyds","da","aswl"]
            },
            test(){
                this.data.count++
                this.data.user.name='赵锦昱'
            }
        })
        vm.test()
        console.log(vm)



</script>
</html>